package com.fbs.wowo.manage.service.imp;

import com.fbs.wowo.exception.ErrorCode;
import com.fbs.wowo.exception.GivenNullParamException;
import com.fbs.wowo.exception.InputVerifyFailedException;
import com.fbs.wowo.exception.NoSuchDataException;
import com.fbs.wowo.manage.entity.UserLogin;
import com.fbs.wowo.manage.mapper.UserLoginMapper;
import com.fbs.wowo.manage.mapper.UserMapper;
import com.fbs.wowo.manage.service.VerifyCodeService;
import com.fbs.wowo.util.common.Generator;
import com.fbs.wowo.util.common.Validator;
import com.fbs.wowo.util.securityutil.SmsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service("verifyCodeService")
@Transactional
public class VerifyCodeServiceImp implements VerifyCodeService {
    // 登录方式
    private static final byte LOGIN_TEL = 1;    // 手机登录
    private static final byte LOGIN_PC = 2;     // 电脑登录
    private static final byte LOGIN_WC = 3;     // 微信登录
    private static final byte LOGIN_WB = 4;     // 微博登录
    private static final byte LOGIN_QQ = 5;     // QQ登录
    private static final byte LOGIN_FB = 6;     // facebook登录

    private static final byte REG = 1;
    private static final byte LOGIN = 0;

    public static final byte Status_Valid = 1;
    public static final byte Status_Invalid = 2;

    /**
     * 发送验证码
     *
     * @param tel 手机号
     * @return userLogin 对象
     * @throws GivenNullParamException
     */
    @Override
    public UserLogin sendVerifyCode(String tel) throws GivenNullParamException {
        Validator.verifyStr(tel);
        if (userMapper.findByTelAndStatus(tel) == null) throw new NoSuchDataException(ErrorCode.ERR_TEL_VERIFY_CODE);

        UserLogin lv = userLoginMapper.findByTel(tel);
        SmsUtils.verifyCodeFrequently(lv.getCreateTime());

        UserLogin record = new UserLogin();
        record.setTel(tel);
        record.setIsReg(LOGIN);
        // 生成验证码
        record.setVerifyCode(Generator.generateVerifyCode(record.getTel()));
        record.setCreateTime(new Date());
        record.setLoginType(LOGIN_PC);
        record.setStatus(Status_Valid);
        // 生成uuid
        if (lv != null) {
            record.setId(lv.getId());
            userLoginMapper.updateByPrimaryKeySelective(record);
        } else {
            // 生成uuid
            record.setId(Generator.generateId());
            userLoginMapper.insertSelective(record);
        }
        record.setVerifyCode(null);
        return record;
    }

    /**
     * 判断验证码是否正确
     * @param tel
     * @param verifyCode
     * @return
     * @throws GivenNullParamException
     * @throws NoSuchDataException
     * @throws InputVerifyFailedException
     */
    @Override
    public UserLogin verifyCode(String tel, String verifyCode) throws GivenNullParamException, NoSuchDataException, InputVerifyFailedException {
        Validator.verifyStr(tel);
        // 按手机号码查询LoginVo，判断验证码输入是否正确
        UserLogin userLoginDb = userLoginMapper.findByTel(tel);
        if (userLoginDb == null) throw new NoSuchDataException(ErrorCode.ERR_TEL_VERIFY_CODE);
        if (userLoginDb.getStatus() == Status_Invalid) throw new NoSuchDataException("验证码失效");
        // 判断验证码是否超时
        SmsUtils.verifyCodeInvalid(userLoginDb.getCreateTime());

        if (!userLoginDb.getVerifyCode().equals(verifyCode)) throw new InputVerifyFailedException(ErrorCode.ERR_VERIFY_CODE);
        // 修改对象使验证码失效
        userLoginDb.setStatus((byte) 2);
        userLoginMapper.updateByPrimaryKeySelective(userLoginDb);
        return userLoginDb;
    }

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserLoginMapper userLoginMapper;
}
